#pragma once
#include "include/cef_resource_handler.h"
#include "include/cef_parser.h"
#include <string>
#include <fstream>
#include <filesystem>

class NanoFileResourceHandler : public CefResourceHandler {
public:
    bool Open(CefRefPtr<CefRequest> request,
        bool& handle_request,
        CefRefPtr<CefCallback> callback) override {
        handle_request = true;
        CefURLParts urlParts;
        CefParseURL(request->GetURL(), urlParts);
        const auto path = std::filesystem::path(CefString(&urlParts.path).ToString()).relative_path();
        fileSize_ = (int64_t)std::filesystem::file_size(path);
        auto ext = path.extension().string();
        ext.erase(std::remove(ext.begin(), ext.end(), '.'), ext.end());
        if (!ext.empty()) {
            fileMimeType_ = CefGetMimeType(ext);
        }
        fileStream_ = std::ifstream(path, std::ios::binary);
        return bool(fileStream_);
    }
    void GetResponseHeaders(CefRefPtr<CefResponse> response,
        int64_t& response_length,
        CefString& redirectUrl) override {
        if (!fileMimeType_.empty()) {
            response->SetMimeType(fileMimeType_);
        }
        response->SetStatus(200);
        response_length = fileSize_;
    }
    void Cancel() { }
    bool Read(void* data_out,
        int bytes_to_read,
        int& bytes_read,
        CefRefPtr<CefResourceReadCallback> callback) {
        bytes_read = -1;
        if (!data_out) {
            bytes_read = -2;
            return false;
        }
        fileStream_.read(static_cast<char*>(data_out), bytes_to_read);
        bytes_read = int(fileStream_.gcount());
        return bytes_read > 0;
    }
private:
    std::ifstream fileStream_;
    int64_t fileSize_ = 0;
    std::string fileMimeType_;

    IMPLEMENT_REFCOUNTING(NanoFileResourceHandler);
};
